using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Rapier.Kodachi.Firefox
{
    public enum NodeEnum { Unknown, Link, Folder }

    public class MozillaNode : Node
    {
        public static void SetUrlComparison()
        {
            Comparison = delegate(Node x, Node y) { return string.Compare(((MozillaNode)x)._href, ((MozillaNode)y)._href); };
        }

        public static void SetNameComparison()
        {
            Comparison = delegate(Node x, Node y) { return string.Compare(((MozillaNode)x).Name, ((MozillaNode)y).Name); };
        }

        static MozillaNode()
        {
            SetNameComparison();
        }

        private NodeEnum _nodeType = NodeEnum.Unknown;
        public NodeEnum NodeType { get { return _nodeType; } }

        public static readonly Regex BeginFolderHTMLMarkup = new Regex(
            @"\<DL\>",
            RegexOptions.IgnoreCase |
            RegexOptions.Singleline);


        public static readonly Regex FolderRegex = new Regex(
            @"<DT><H3.*?(ADD_DATE=\""(.*?)\"")* ID=""(.*?)"".*?>(.*?)<\/H3>",
            RegexOptions.IgnoreCase |
            RegexOptions.Singleline);


        //match a link
        private static readonly Regex LinkRegex = new Regex(
            @"<DT><A HREF=""(.+?)"".*?>(.*?)<\/A>",
            RegexOptions.IgnoreCase |
            RegexOptions.Singleline);


        public static readonly Regex EndFolderHTMLMarkup =
            new Regex(@"\<\/DL\>",
            RegexOptions.IgnoreCase |
            RegexOptions.Singleline);



        private string _name = "";
        public string Name
        {
            get { return _name; }
        }

        private string _href = "";
        public string Href
        {
            get { return _href; }
        }

        private string _line;


        public static bool IsLinkLine(string line)
        {
            return LinkRegex.IsMatch(line);
        }

        public static bool IsFolderLine(string line)
        {
            return FolderRegex.IsMatch(line);
        }

        public bool IsFolder { get { return _nodeType == NodeEnum.Folder; } }
        public bool IsLink { get { return _nodeType == NodeEnum.Link; } }

        public string Line
        {
            get { return _line; }
        }


        public static MozillaNode Create(MozillaNode parent, string originalLine)
        {

            MozillaNode node = new MozillaNode();
            if (MozillaNode.IsFolderLine(originalLine) || MozillaNode.IsLinkLine(originalLine))
            {

                SetRelationShip(parent, node);
                node._line = originalLine;
                if (MozillaNode.IsFolderLine(originalLine))
                {
                    node._nodeType = NodeEnum.Folder;
                    Match match = FolderRegex.Match(originalLine);
                    node._name = match.Groups[4].Value;
                }
                else
                {
                    node._nodeType = NodeEnum.Link;
                    Match match = LinkRegex.Match(originalLine);
                    node._href = match.Groups[1].Value;
                    node._name = match.Groups[2].Value;
                    if (string.IsNullOrEmpty(node._href) || string.IsNullOrEmpty(node._name))
                    {
                        throw new ArgumentException("_href or _name not set properly");
                    }
                }
            }
            return node;
        }


        private MozillaNode()
        {

        }


        public static MozillaNode Create(string name)
        {
            MozillaNode node = new MozillaNode();
            node._name = name;
            node._href = "root";
            node._line = "root";
            return node;
        }

        public override string ToString()
        {
            const string message = "Href [{0}] Parent [{1}]";
            return string.Format(message, (this._href ?? "<href??>"), (this.Parent == null ? "null" : "Parent"));
        }

        public override bool IsValid
        {
            get
            {
                bool izNoGood = this.IsLink && string.IsNullOrEmpty(this._href);
                return !izNoGood;
            }
        }
    }
}
